﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;
using System.IO;
using System.Reflection;
using IbsysII.Domain;


namespace IbsysII.Util
{
    //Klasse Stammdaten zur Datenintegration in die Anwendung
    //Quelle ist die Excel Datei Stammdaten.xlsx
    //Alle Stammdaten werden in dieser Datei gepflegt
    //Zum Start des Programms werden im ersten Schritt die benoetigten Objekte erstellt und mit den Stammdaten angereichert
    //[Im Zweiten Schritt werden die Objekte (mit den Stammdaten) mit Bewegungsdaten angereichert, diese entstammen der scsim XML Datei]
    class Stammdaten
    {

        static Stammdaten st = new Stammdaten();

        public static string nameWsP1= "P1";
        public static string nameWsP2= "P2";
        public static string nameWsP3= "P3";
        public static string nameWsArbeitsplaetze= "Arbeitsplaetze";

        //Laedt alle Stammdaten zu einem Teil in eine Liste von Listen
        public static List<List<Teil>> ladeTeileStammdaten() {
            List<List<Teil>> lstAlleTeile = new List<List<Teil>>();
            
            string projectPath = Environment.CurrentDirectory;
            //Für Setup auskoomentieren
            for (int i = 0; i < 2; i++)
            {
                projectPath = System.IO.Path.GetDirectoryName(projectPath);
            }
            projectPath = projectPath + @"\Daten\Stammdaten.xlsx";

            //Strukturstueckliste fuer jedes Produkt (P1-P1) laden
            try
            {
                lstAlleTeile.Add(ladeTeileFromExcel(nameWsP1));
                lstAlleTeile.Add(ladeTeileFromExcel(nameWsP2));
                lstAlleTeile.Add(ladeTeileFromExcel(nameWsP3));
            }
            catch (Exception e) { }
            return lstAlleTeile;

        }

        //Laden der einzelnen Stuecklisten in Objektform (verkette Listen)
        public static List<Teil> ladeTeileFromExcel(string pNameWs) {
            List<Teil> lstTeile = new List<Teil>();

            //Arbeitsplaetze laden  da diese fuer die Stammdaten der Teile benoetigt werden
            List<Arbeitsplatz> arbeitsplatzLst = ladeArbeitsplaetzeFromExcel();

            App.xlWs = (Microsoft.Office.Interop.Excel.Worksheet)App.xlWb.Worksheets.get_Item(pNameWs);
            App.xlRng = App.xlWs.UsedRange;

           try
            {
                for (int rCnt = 2; rCnt <= App.xlRng.Rows.Count; rCnt++)
            {

                    //Erstellen und Setzen der zugehoerigen Daten zu einem TeilObjekt
                    Teil teil = new Teil();
                    teil.Level = (int)(App.xlRng.Cells[rCnt, 1] as Microsoft.Office.Interop.Excel.Range).Value2;
                    teil.TeilNr = (int)(App.xlRng.Cells[rCnt, 2] as Microsoft.Office.Interop.Excel.Range).Value2;
                    teil.Stuecklistenmenge = (int)(App.xlRng.Cells[rCnt, 3] as Microsoft.Office.Interop.Excel.Range).Value2;
                    teil.GehtEin = (int)(App.xlRng.Cells[rCnt, 4] as Microsoft.Office.Interop.Excel.Range).Value2;
                    teil.Teileart = Convert.ToChar((App.xlRng.Cells[rCnt, 5] as Microsoft.Office.Interop.Excel.Range).Value2);
                    teil.Bezeichnung = (string)(App.xlRng.Cells[rCnt, 6] as Microsoft.Office.Interop.Excel.Range).Value2;
                    teil.Diskontmenge = (int)(App.xlRng.Cells[rCnt, 7] as Microsoft.Office.Interop.Excel.Range).Value2;
                    teil.Bestellkosten = (double)(App.xlRng.Cells[rCnt, 8] as Microsoft.Office.Interop.Excel.Range).Value2;
                    teil.Lieferzeit = (double)(App.xlRng.Cells[rCnt, 9] as Microsoft.Office.Interop.Excel.Range).Value2;
                    teil.Lieferzeitabweichung = (double)(App.xlRng.Cells[rCnt, 10] as Microsoft.Office.Interop.Excel.Range).Value2;
                    teil.Gleichteil =Convert.ToChar((App.xlRng.Cells[rCnt, 14] as Microsoft.Office.Interop.Excel.Range).Value2);
                    teil.Sicherheitsbestand = (int)((App.xlRng.Cells[rCnt, 15] as Microsoft.Office.Interop.Excel.Range).Value2);
                   
                    //Ergaenzung der Arbeitsplatze ueber Arbeitsschritte, nur E-Teile => wo wird gefertigt
                    if (teil.Teileart == 'P' || teil.Teileart == 'E')
                     {
                         string strukturArbeitsliste = (App.xlRng.Cells[rCnt, 11] as Microsoft.Office.Interop.Excel.Range).Value2.ToString();
                         string[] strukturArbeitslisteFeld = strukturArbeitsliste.Split(';');
                         string strukturFertigungszeit = (App.xlRng.Cells[rCnt, 12] as Microsoft.Office.Interop.Excel.Range).Value2.ToString();
                         string[] strukturFertigungszeitFeld = strukturFertigungszeit.Split(';');
                         string strukturRuestzeitliste = (App.xlRng.Cells[rCnt, 13] as Microsoft.Office.Interop.Excel.Range).Value2.ToString();
                         string[] strukturRuestzeitlisteFeld = strukturRuestzeitliste.Split(';');

                         if (strukturArbeitslisteFeld.Length == 1)
                         {
                             Arbeitsschritt arbeitsschritt = new Arbeitsschritt();
                             arbeitsschritt.Arbeitsplatz = (from arbeitsplatz in arbeitsplatzLst where arbeitsplatz.ArbeitsplatzNr == Convert.ToInt32(strukturArbeitsliste) select arbeitsplatz).SingleOrDefault();
                             arbeitsschritt.Fertigungszeit = Convert.ToInt32(strukturFertigungszeit);
                             arbeitsschritt.Ruestzeit = Convert.ToInt32(strukturRuestzeitliste);
                             teil.lstArbeitschritt.Add(arbeitsschritt);
                         }
                         else
                         {
                             for (int i = 0; i < strukturArbeitslisteFeld.Length; i++)
                             {
                                 Arbeitsschritt arbeitsschritt = new Arbeitsschritt();
                                 arbeitsschritt.Arbeitsplatz = (from arbeitsplatz in arbeitsplatzLst where arbeitsplatz.ArbeitsplatzNr == Convert.ToInt32(strukturArbeitslisteFeld[i]) select arbeitsplatz).SingleOrDefault();
                                 arbeitsschritt.Fertigungszeit = Convert.ToInt32(strukturFertigungszeitFeld[i]);
                                 arbeitsschritt.Ruestzeit = Convert.ToInt32(strukturRuestzeitlisteFeld[i]);
                                 teil.lstArbeitschritt.Add(arbeitsschritt);
                             }
                         }
                     }
                     
                    lstTeile.Add(teil);
                }
                
            }
           catch (Exception e)
           {
               Console.WriteLine(e.Message + " - Fehlende Stammdaten in Worksheet: " + pNameWs);
           }

           //finally
           //{
           //    xlWb.Close(true, null, null);
           //    xlApp.Quit();
           //}


            //Stueckliste erstellen (verkette Listen)
            List<Teil> stueckliste = new List<Teil>();

            //Fuer jedes Teil muss die Liste jeweils einmal durchgegangen werden => 2 Schleifen
            //fuer ein Teil i in lstTeile
            for (int i = 0; i < lstTeile.Count; i++)
            {
                //fuer jedes Teil j in lstTeile
                for (int j = 0; j < lstTeile.Count; j++)
                {
                    //Falls die Teilenummer der GehtEinNummer entspricht hinzufuegen
                    if (lstTeile[j].TeilNr == lstTeile[i].GehtEin)
                    {
                        lstTeile[j].lstZuordnung.Add(lstTeile[i]);
                    }
                }
            }
            return lstTeile;
            
        }

        //Lade alle Arbeitsplaetze
        public static List<Arbeitsplatz> ladeArbeitsplaetzeFromExcel() {

            string projectPath = Environment.CurrentDirectory;

            for (int i = 0; i < 2; i++)
            {
                projectPath = System.IO.Path.GetDirectoryName(projectPath);
            }
            projectPath = projectPath + @"\Daten\Stammdaten.xlsx";

            App.xlWs = (Microsoft.Office.Interop.Excel.Worksheet)App.xlWb.Worksheets.get_Item(nameWsArbeitsplaetze);
            App.xlRng = App.xlWs.UsedRange;

            List<Arbeitsplatz> lstArbeitsplaetze = new List<Arbeitsplatz>();
            List<Schicht> lstSchicht = new List<Schicht>();
            try{
                for (int rCnt = 2; rCnt <= App.xlRng.Rows.Count; rCnt++)
            {
                    Schicht schicht1 = new Schicht();
                    Schicht schicht2 = new Schicht();
                    Schicht schicht3 = new Schicht();

                    schicht1.SchichtNr = 1;
                    schicht2.SchichtNr = 2;
                    schicht3.SchichtNr = 3;

                    schicht1.Lohn = (double)(App.xlRng.Cells[rCnt, 4] as Microsoft.Office.Interop.Excel.Range).Value2;
                    schicht2.Lohn = (double)(App.xlRng.Cells[rCnt, 5] as Microsoft.Office.Interop.Excel.Range).Value2;
                    schicht3.Lohn = (double)(App.xlRng.Cells[rCnt, 6] as Microsoft.Office.Interop.Excel.Range).Value2;

                    schicht1.LohnUeberstunden = (double)(App.xlRng.Cells[rCnt, 7] as Microsoft.Office.Interop.Excel.Range).Value2;
                    schicht2.LohnUeberstunden = (double)(App.xlRng.Cells[rCnt, 7] as Microsoft.Office.Interop.Excel.Range).Value2;
                    schicht3.LohnUeberstunden = (double)(App.xlRng.Cells[rCnt, 7] as Microsoft.Office.Interop.Excel.Range).Value2;

                    lstSchicht.Add(schicht1);
                    lstSchicht.Add(schicht2);
                    lstSchicht.Add(schicht3);

                    Arbeitsplatz ap = new Arbeitsplatz();
                    ap.ArbeitsplatzNr = (int)(App.xlRng.Cells[rCnt, 1] as Microsoft.Office.Interop.Excel.Range).Value2;
                    ap.VarMaschKosten = (double)(App.xlRng.Cells[rCnt, 2] as Microsoft.Office.Interop.Excel.Range).Value2;
                    ap.FixMaschKosten = (double)(App.xlRng.Cells[rCnt, 3] as Microsoft.Office.Interop.Excel.Range).Value2;
                    ap.lstStammdatenSchicht = lstSchicht;
                    lstArbeitsplaetze.Add(ap);
                }
               
            }
            catch (Exception e)
            {

            }
            return lstArbeitsplaetze;
        
        }

        public void CloseExcel()
        {
            if (App.xlApp != null)
            {
                NAR(App.xlWb);
;
                App.xlApp.Quit();
                NAR(App.xlApp);
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
        }

        public void NAR(object oEx)
        {
            try
            {
                App.xlWb.Close(false, null, null);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(oEx);
                 
            }
            catch { }
            finally
            {
                oEx = null;
            }
        } 

    }
}
